#pragma once

#define inline _inline
#ifndef INT64_C
#define UINT64_C(val) val##ui64
#define INT64_C(val)  val##i64
#endif

extern "C"
{   
#include "libavcodec\avcodec.h"
#include "libavformat\avformat.h"
#include "libswscale\swscale.h"
}  

#include "apThread.h"
#include "apFifoBuffer.h"
#include "apCritSec.h"

struct video_header
{
	LONGLONG pts;
	LONGLONG dts;
};

class apFFreader: public apThread
{
public:
	apFFreader(void);
	~apFFreader(void);
	bool		Open(const char *filename);
	bool		StartDecoding();
	int			GetWidth(){return m_width;}
	int			GetHeight(){return m_height;}
	LONGLONG	GetTimeBase(){return m_timebase.den;}//need fix
	LONGLONG	GetDuration(){return m_duration;}
	double		GetFrameRate(){return m_fps;}
	bool		ReadFrame(char *buf, int *bufSize, LONGLONG *timeStamp);//msec
	void		Close();
	bool		Seek(LONGLONG timestamp);
protected:
	virtual void thread_proc();
private:
	static void log_callback(void* ptr, int level, const char* fmt, va_list vl);
	AVFrame* alloc_picture(int pix_fmt, int width, int height);
private:
	AVFormatContext*	m_pInFmtCtx;
	AVCodecContext*		m_pInCodecCtx;
	int					m_videoStream;
	int					m_audioStream;
	AVRational			m_timebase;
	struct SwsContext*	m_img_convert_ctx;
	AVFrame*			m_pFrame;
	AVFrame*			m_pOutFrame;
	int					m_width;
	int					m_height;
	double				m_fps;
	LONGLONG			m_curFrameNo;
	LONGLONG			m_totalFrameNo;
	LONGLONG			m_duration;
	apFifoBuffer		m_videoFifo;
	int					m_videoFifoSize;
	HANDLE				m_StopEvt;
	CBaseCritSec		m_cs;
	bool				m_bDecoding;
};
